/**
 * Created by zhaojiuyang1 on 15/5/4.
 */

var Q = require("q");
var gDb = null;
var connectMysql = require("../utils.js").connectMysql;
var exec = require("child_process").exec;
var http = require("http");
var querystring = require("querystring");
var _ = require("underscore");
var moment = require("moment");
var errorMap = require(__dirname+"/../config/ErrorCode.js").ERRORMAP;
var log4js = require('log4js');
//获取该js的log
var log = log4js.getLogger("userHelper");
var config ;
var init = function(options){
    config = options;
    gDb = options.mysql;
};
exports.init = init;
var getTest = function(){
    var deferred = Q.defer();
    var sql = "select * from user where id = ?";
    var sqlValues = [];
    sqlValues.push("1464015855626");
    gDb.query(sql, sqlValues, function(err, results){
        if (!err) {
            log.info(results);
            deferred.resolve(results);
        } else {
            deferred.reject(err);
        }
    });
    return deferred.promise;
};
exports.getTest = getTest;

/**
 * 获取6位验证码
 * @returns {number} 验证码
 */
var getIdentifyingCode = function(){
    var code = Math.random();
    code = Math.round((code * 1000 * 1000));
    if(code < 100000){
        code = getIdentifyingCode();
    }
    return Q(code);
};
/**
 * 短信发送
 * @param mobile
 * @param content
 * @returns {*|promise}
 */
var sendSMS = function(mobile,content,callback){
    var deferred = Q.defer();
    var postData = querystring.stringify({
        'mobile' : mobile,
        content : content
    });
    var options = _.extend(config.sms);
    log.info(options);
    _.defaults(options,{
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': postData.length
        }
    });
    log.info(options);
    //options = {
    //    "host":"123.57.49.152",
    //    "port":8089,
    //    "path":"/sms_server/sms/send",
    //    method: 'POST',
    //    headers: {
    //        'Content-Type': 'application/x-www-form-urlencoded',
    //        'Content-Length': postData.length
    //    }
    //};

    var req = http.request(options, function(res) {
        log.info('STATUS: ' + res.statusCode);
        log.info('HEADERS: ' + JSON.stringify(res.headers));
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            log.info('BODY: ' + chunk);
            deferred.resolve(_.isString(chunk)?JSON.parse(chunk):chunk);
        });
    }).on("error",function(err){
        log.info(err);
        deferred.reject(err);
    });
    req.write(postData);
    req.end();
    return deferred.promise.nodeify(callback);
};
/**
 * 插入验证码
 * @param options
 * @param callback
 */
var insertCode = function(options,callback){
    log.info("insertCode");
    var deferred = Q.defer();
    var sql = "INSERT INTO identifying_code(mobile,identifying_code,dtime,ctime) " +
        "values( ?,? ,ADDTIME(SYSDATE(),\"00:02:00\"),SYSDATE())";
    var sqlValues = [];
    sqlValues.push(options["mobile"]);
    sqlValues.push(options["code"]);
    //var now = moment();
    //sqlValues.push(now.add(2,"minute"));
    //sqlValues.push(now);
    log.info(sqlValues);
    gDb.query(sql, sqlValues, function(err, results){
        if (!err) {
            log.info(results);
            deferred.resolve(results);
        } else {
            log.info(err);
            deferred.reject(err);
        }
    });
    deferred.promise.nodeify(callback);
};

/**
 * 处理短信验证码的操作
 * 生成验证码，验证码入库，发送短信
 * @param options 手机号码
 * @param callback
 * @returns {*}
 */
var sendInvitation = function(options,callback){
    var deferred = Q.defer();
    var in_code ;
    var content ;
    getIdentifyingCode()
        .then(function(code){
            in_code = code;
            content = "【嘟嘟导优】"+code+"（短信验证码），感谢您使用嘟嘟导优！";
            log.info(content);
            return insertCode({mobile:options.mobile,code:code});
        })
        .then(function(results){
            return sendSMS(options.mobile,content)
        })
        .then(function(result){
            var res_obj = _.isObject(result) ? result : JSON.parse(result);
            res_obj["code"] = in_code;
            deferred.resolve(result);
        }).fail(function(err){
            log.info(err);
            deferred.reject(err);
        });
    return deferred.promise.nodeify(callback);
};
exports.sendInvitation = sendInvitation;
/**
 * 验证验证码是否正确
 * @param options
 * @param callback
 * @returns {*}
 */
var checkIdentifyingCode = function(options){
    var deferred = Q.defer();
    var sql = "select count(id) count from identifying_code " +
        "where mobile = "+options.mobile+" and identifying_code = "+options.identifyCode+" and dtime > sysdate()";
    gDb.query(sql, [], function(err, results){
        if (!err) {
            log.info(results);
            deferred.resolve(results[0]["count"]>0);
        } else {
            log.info(err);
            deferred.reject(err);
        }
    });
    return deferred.promise;
};
/**
 * 验证邀请码是否正确,并获取uid
 * @param options
 * @param callback
 * @returns {*}
 */
var checkInvitation = function(options){
    var deferred = Q.defer();
    var sql = "select t.uid as uid,t.invitation_code as invitation_code from tourist t where t.invitation_code = ?";
    gDb.query(sql, [options.invitationCode], function(err, results){
        if (!err) {
            log.info(results);
            if(_.isEmpty(results)){
                deferred.resolve(null);
            }else{
                deferred.resolve(results[0]);
            }
        } else {
            log.info(err);
            deferred.reject(err);
        }
    });
    return deferred.promise;
};
/**
 * 创建用户表数据
 * @param options
 * @param callback
 * @returns {*}
 */
var insertUser = function(options){
    var deferred = Q.defer();
    //实际创建user
    var insertUser = function(options){
        var deferred = Q.defer();
        var sql = "INSERT INTO user(id,mobile,ctime) " +
            "values( ?,? ,SYSDATE())";
        var sqlValues = [];
        sqlValues.push(options["id"].trim());
        sqlValues.push(options["mobile"]);
        log.info(sqlValues);
        gDb.query(sql, sqlValues, function(err, results){
            if (!err) {
                deferred.resolve(options);
            } else {
                log.info(err);
                deferred.reject(err);
            }
        });
        return deferred.promise;
    };
    getUserId().then(function(seq){
        return execMathLong(seq);
    }).then(function(id){
        return insertUser({id:id,mobile:options.mobile});
    }).then(function(result){
        deferred.resolve(result);
    }).fail(function(err){
        deferred.reject(err);
    });

    return deferred.promise;
};
/**
 * 创建导游表数据
 * @param options
 * @param callback
 * @returns {*}
 */
var insertGuide = function(options){
    var deferred = Q.defer();
    var insertGuide = function(options){
        var deferred = Q.defer();
        var sql = "INSERT INTO guide(id,mobile,uid,ctime,utime) " +
            "values( ?,? ,?,SYSDATE(),SYSDATE())";
        var sqlValues = [];
        sqlValues.push(options["id"]);
        sqlValues.push(options["mobile"]);
        //sqlValues.push(options["invitationCode"]);
        sqlValues.push(options["uid"]);
        log.info(sqlValues);
        gDb.query(sql, sqlValues, function(err, results){
            if (!err) {
                deferred.resolve(options);
            } else {
                log.info(err);
                deferred.reject(err);
            }
        });
        return deferred.promise;
    };
    getGuideId().then(function(seq){
        return execMathLong(seq);
    }).then(function(id){
        options["id"] = id;
        return insertGuide(options);
    }).then(function(result){
        return deferred.resolve(result);
    }).fail(function(err){
        deferred.reject(err);
    });
    return deferred.promise;
};
/**
 * 创建邀请码记录表数据
 * @param options
 * @returns {*}
 */
var insertInvitation = function(options){
    var deferred = Q.defer();
    var sql = "INSERT INTO invitation(from_uid,from_type,invitation_code,to_uid,to_type,reg_time,first_time,ctime) " +
        "values( ?,\"D\" ,?,?,\"G\",SYSDATE(),null,SYSDATE())";
    var sqlValues = [];
    sqlValues.push(options["fromUid"]);
    sqlValues.push(options["invitationCode"]);
    sqlValues.push(options["uid"]);
    log.info(sqlValues);
    gDb.query(sql, sqlValues, function(err, results){
        if (!err) {
            log.info(results);
            deferred.resolve(results);
        } else {
            log.info(err);
            deferred.reject(err);
        }
    });
    return deferred.promise;
};
/**
 * 获取userId
 * @returns {*}
 */
var getUserId = function(){
    var deferred = Q.defer();
    var sql = "select nextval('seq_user') as seq";
    gDb.query(sql, [], function(err, results){
        if (!err) {
            log.info(results);
            deferred.resolve(results[0]["seq"]);
        } else {
            log.info(err);
            deferred.reject(err);
        }
    });
    return deferred.promise;
};
/**
 * 获取guideId
 * @returns {*}
 */
var getGuideId = function(){
    var deferred = Q.defer();
    var sql = "select nextval('seq_guide') as seq";
    gDb.query(sql, [], function(err, results){
        if (!err) {
            log.info(results);
            deferred.resolve(results[0]["seq"]);
        } else {
            log.info(err);
            deferred.reject(err);
        }
    });
    return deferred.promise;
};

var execMathLong = function(seq){
    var deferred = Q.defer();
    var execStr = "echo $((("+moment().unix()+") << 10 | ("+seq+" % 1024))) ";
    exec(execStr, function (error, stdout, stderr) {
        if (error !== null) {
            return deferred.reject(error);
        }
        return deferred.resolve(stdout);
    });
    return deferred.promise;
};
/**
 *
 * @param options
 * @returns {*|promise}
 */
var checkMobileExist = function(options){
    var deferred = Q.defer();
    var sql = "select count(id) count from user " +
        "where mobile = "+options.mobile;
    gDb.query(sql, [], function(err, results){
        if (!err) {
            log.info(results);
            deferred.resolve(results[0]["count"]>0);
        } else {
            log.info(err);
            deferred.reject(err);
        }
    });
    return deferred.promise;
};

var signUp = function(options,callback){
    var deferred = Q.defer();
    _.defaults(options,{
        mobile:null,
        identifyCode:null,
        invitationCode:null
    });
    gDb.beginTransaction(function(err){
        if(err){deferred.reject(err);}
        checkIdentifyingCode(options)
            .then(function(result){
                log.info(result);
                if(result === true){
                    return checkMobileExist(options);
                }
                return Q.reject(errorMap.indentifyCodeErr);
            })
            .then(function(result){
                log.info("run after checkMobileExist");
                log.info(result);
                if(result !== true){
                    return checkInvitation(options);
                }else{
                    return Q.reject(errorMap.mobileExist);
                }
            }).then(function(result){
                log.info("run after checkInvitation");
                log.info(result);
                if(_.isEmpty(result)){
                    log.info("run after checkInvitation is empty");
                    return Q.reject(errorMap.invitationCodeErr)
                }else{
                    options["fromUid"] = result["uid"];
                    return insertUser({mobile:options["mobile"]});
                }
            }).then(function(result){
                log.info(result);
                options["uid"] = result["id"];
                return insertGuide(options);
            }).then(function(result){
                log.info(result);
                return insertInvitation(options);
            }).then(function(result){
                log.info(result);
                gDb.commit(function(err) {
                    if (err) {
                        gDb.rollback(function() {
                            deferred.reject(err);
                        });
                    }else{
                        deferred.resolve(result);
                    }
                });

            }).fail(function(err){
                log.error(err);
                gDb.rollback(function() {
                    deferred.reject(err);
                });
                deferred.reject(err);
            }).catch(function(err){
                log.error(err);
                gDb.rollback(function() {
                    deferred.reject(err);
                });
                deferred.reject(err);
            });
    });

    return deferred.promise.nodeify(callback);
};
exports.signUp = signUp;
exports.checkMobileExist = checkMobileExist;
exports.execMathLong = execMathLong;
exports.getGuideId = getGuideId;
exports.getUserId = getUserId;
exports.checkInvitation = checkInvitation;
exports.checkIdentifyingCode = checkIdentifyingCode;
exports.insertUser=insertUser;
exports.insertGuide=insertGuide;


